package com.android.jianboshi.bean;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.List;
import java.util.UUID;

/**
 * 保存蓝牙广播数据
 */
public class BtParseInfo {

    private byte flags;
    private List<UUID> uuids;
    private String localName;
    private Short manufacturer;

    public BtParseInfo(byte[] advData) {
        // 5.0以下版本, 由BluetoothAdapter.LeScanCallback回调得到advData
        ByteBuffer buffer = ByteBuffer.wrap(advData).order(ByteOrder.LITTLE_ENDIAN);
        while (buffer.remaining() > 2) {
            byte length = buffer.get();
            if (length == 0)
                break;

            byte type = buffer.get();
            length -= 1;
            switch (type) {
                case 0x01: // Flags
                    /**
                     * bit 0: LE 有限发现模式
                     * bit 1: LE 普通发现模式
                     * bit 2: 不支持 BR/EDR
                     * bit 3: 对 Same Device Capable(Controller) 同时支持 BLE 和 BR/EDR
                     * bit 4: 对 Same Device Capable(Host) 同时支持 BLE 和 BR/EDR
                     * bit 5..7: 预留
                     */
                    this.flags = buffer.get();
                    length--;
                    break;
                case 0x02: // Partial list of 16-bit UUIDs
                case 0x03: // Complete list of 16-bit UUIDs
                case 0x14: // List of 16-bit Service Solicitation UUIDs
                    /**
                     * 非完整的 16 bit UUID 列表： TYPE = 0x02;
                     * 完整的 16 bit UUID 列表： TYPE = 0x03;
                     * 非完整的 32 bit UUID 列表： TYPE = 0x04;
                     * 完整的 32 bit UUID 列表： TYPE = 0x05;
                     * 非完整的 128 bit UUID 列表： TYPE = 0x06;
                     * 完整的 128 bit UUID 列表： TYPE = 0x07;
                     * 16 bit UUID 列表： TYPE = 0x14
                     * 32 bit UUID 列表： TYPE = 0x??
                     * 128 bit UUID 列表： TYPE = 0x15
                     */
                    while (length >= 2) {
                        this.uuids.add(UUID.fromString(String.format(
                                "%08x-0000-1000-8000-00805f9b34fb", buffer.getShort())));
                        length -= 2;
                    }
                    break;
                case 0x04: // Partial list of 32 bit service UUIDs
                case 0x05: // Complete list of 32 bit service UUIDs
                    while (length >= 4) {
                        this.uuids.add(UUID.fromString(String.format(
                                "%08x-0000-1000-8000-00805f9b34fb", buffer.getInt())));
                        length -= 4;
                    }
                    break;
                case 0x06: // Partial list of 128-bit UUIDs
                case 0x07: // Complete list of 128-bit UUIDs
                case 0x15: // List of 128-bit Service Solicitation UUIDs
                    while (length >= 16) {
                        long lsb = buffer.getLong();
                        long msb = buffer.getLong();
                        this.uuids.add(new UUID(msb, lsb));
                        length -= 16;
                    }
                    break;
                case 0x08: // Short local device name
                case 0x09: // Complete local device name
                    /**
                     * 设备全名： TYPE = 0x08
                     * 设备简称： TYPE = 0x09
                     */
                    byte sb[] = new byte[length];
                    buffer.get(sb, 0, length);
                    length = 0;
                    this.localName = new String(sb).trim();
                    break;
                case (byte) 0xFF: // Manufacturer Specific Data
                    /**
                     * 厂商自定义数据: TYPE = 0xFF
                     * 厂商自定义的数据中，前两个字节表示厂商 ID，剩下的是厂商自己按照需求添加，里面的数据内容自己定义
                     */
                    this.manufacturer = buffer.getShort();
                    length -= 2;
                    break;
                default: // skip
                    break;
            }
            if (length > 0) {
                buffer.position(buffer.position() + length);
            }
        }
    }

    public byte getFlags() {
        return flags;
    }

    public List<UUID> getUuids() {
        return uuids;
    }

    public String getLocalName() {
        return localName;
    }

    public Short getManufacturer() {
        return manufacturer;
    }
}
